<?php declare(strict_types=1);

namespace Zyucv7\Core\ORM;

use Zyucv7\Core\ORM\Query;
use Zyucv7\Core\Config\Config;
use Zyucv7\Core\Database\Manager as DatabaseManager;
use Zyucv7\Core\Database\Driver as DatabaseDriver;
use Zyucv7\Core\Database\DatabaseException;

/**
 * 模型抽象基类
 */
abstract class Model
{
    /** @var string 关键字段名 */
    protected $primaryKey = 'id';
    protected $createdAt = '';
    protected $updateAt = '';

    /** @var string 数据库连接名 */
    protected $connection = 'default';

    /** @var DatabaseDriver 数据库对象 */
    protected DatabaseDriver $db;

    /** @var string 表名 */
    protected $table;

    /** @var array 属性数组 */
    protected $attributes = [];

    /** @var Query query对象 */
    protected $query = null;

    /** @var string 时间戳的格式，默认是datetime*/
    protected $dateFormat = 'datetime';


    public function __construct()
    {
        $this->getConnection();
    }

    /**
     * 获取数据库连接（伪代码）
     * @return mixed
     */
    protected function getConnection()
    {
        // 伪代码：实际项目中这里应该返回数据库连接实例
        $config_key = 'databases.' . $this->connection;
        $config = Config::get($config_key);
        $this->db = DatabaseManager::connect($config);
    }

    /**
     * 创建查询构造器
     * @return Query
     */
    public function newQuery(): Query
    {
        $this->query = new Query($this->table, $this->db);
        return $this->query;
    }

    /**
     * 保存记录（自动判断新增或更新）
     * @return void
     */
    public function save($data): int
    {
        $id = intval($data[$this->primaryKey] ?? 0);

        if ($id) {
            unset($data[$this->primaryKey]);
            $this->update($data, $id);
        } else {
            $id = $this->insert($data);
        }

        return $id;
    }

    /**
     * 新增记录
     * @return bool
     */
    public function insert($data): int
    {
        $time_val = ($this->dateFormat == 'timestamp' ? time() : date('Y-m-d H:i:s'));
        if (!isset($data[$this->createdAt]) && $this->createdAt) {
            $data[$this->updateAt] = $time_val;
        }
        if (!isset($data[$this->updateAt]) && $this->updateAt) {
            $data[$this->updateAt] = $time_val;
        }
        $id = $this->db->insert($this->table, $data);
        return $id;
    }

    /**
     * 更新记录
     * @return bool
     */
    public function update($data, $id): bool
    {
        $primaryKey = $this->primaryKey;
        $where = $primaryKey.' = ?';
        // 如果没有传递更新时间，则自动更新
        if (!isset($data[$this->updateAt]) && $this->updateAt) {
            $data[$this->updateAt] = ($this->dateFormat == 'timestamp' ? time() : date('Y-m-d H:i:s'));
        }
        $aff_rows = $this->db->update($this->table, $data, $where, [ $id ]);
        return ($aff_rows > 0);
    }

    /**
     * 更新所有匹配的记录
     * @return bool
     */
    protected function updateAll($data, $where, $params): bool
    {
        $aff_rows = $this->db->update($this->table, $data, $where, $params);
        return ($aff_rows > 0);
    }

    /**
     * 删除记录
     * @return bool
     */
    public function delete($id): bool
    {
        $primaryKey = $this->primaryKey;

        if (intval($id) == 0) {
            throw DatabaseException::InvalidArgument('Delete ID is zero.');
        }

        $where = $primaryKey.'= ?';

        $aff_rows = $this->db->delete($this->table, $where, [$id]);
        return ($aff_rows > 0);
    }

    /**
     * 删除所有匹配的记录
     * @return bool
     */
    public function deleteAll($where, $params): bool
    {
        $aff_rows = $this->db->delete($this->table, $where, $params);
        return ($aff_rows > 0);
    }

    /**
     * 获取完整的SQL
     */
    public function getSQL() {
        return $this->db->getRawSQL();
    }

    /**
     * 获取真实表名
     */
    public function getTableName(string $table = '', string $alias = ''): string {
        return $this->db->getTableName(($table ? $table : $this->table), $alias);
    }
}